#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "csv_parse.h"

// 比较函数（用于qsort和bsearch）
static int compareObjects(const void *a, const void *b) {
    const ObjectInfo *objA = (const ObjectInfo *)a;
    const ObjectInfo *objB = (const ObjectInfo *)b;
    return objA->label - objB->label;
}

// 解析CSV文件并返回排序后的对象数组
ObjectInfo* parseCsvFile(const char *filename, int *count) {
    if (!filename || !count) {
        errno = EINVAL;
        return NULL;
    }

    FILE *file = fopen(filename, "r");
    if (!file) {
        return NULL;
    }

    // 估算行数（假设每行平均100字节）
    fseek(file, 0, SEEK_END);
    long fileSize = ftell(file);
    rewind(file);
    int estimatedCount = fileSize / 100; // 预估行数

    // 分配初始数组（动态扩展）
    int capacity = estimatedCount > 0 ? estimatedCount : 1000;
    ObjectInfo *objects = (ObjectInfo *)malloc(capacity * sizeof(ObjectInfo));
    if (!objects) {
        fclose(file);
        return NULL;
    }

    *count = 0;
    char line[512];

    // 解析每一行
    while (fgets(line, sizeof(line), file)) {
        // 调整数组容量
        if (*count >= capacity) {
            capacity *= 2;
            objects = (ObjectInfo *)realloc(objects, capacity * sizeof(ObjectInfo));
            if (!objects) {
                fclose(file);
                return NULL;
            }
        }

        // 移除换行符
        char *newline = strchr(line, '\n');
        if (newline) *newline = '\0';

        // 解析字段
        char *token = strtok(line, ",");
        if (!token) continue;
        objects[*count].label = atoi(token);

        token = strtok(NULL, ",");
        if (!token) continue;
        strncpy(objects[*count].english, token, sizeof(objects[*count].english) - 1);

        token = strtok(NULL, ",");
        if (!token) continue;
        strncpy(objects[*count].chinese, token, sizeof(objects[*count].chinese) - 1);

        token = strtok(NULL, ",");
        if (!token) continue;
        strncpy(objects[*count].category, token, sizeof(objects[*count].category) - 1);

        (*count)++;
    }

    fclose(file);

    // 按label排序（为二分查找做准备）
    qsort(objects, *count, sizeof(ObjectInfo), compareObjects);

    return objects;
}

// 使用二分查找根据label值查找对象信息
ObjectInfo* findObjectByLabel(ObjectInfo *objects, int count, int label) {
    if (!objects || count <= 0) {
        return NULL;
    }

    ObjectInfo key = {label};
    return (ObjectInfo *)bsearch(&key, objects, count, sizeof(ObjectInfo), compareObjects);
}

// 释放对象数组内存
void freeObjects(ObjectInfo *objects) {
    if (objects) {
        free(objects);
    }
}